package com.uniflow.controller;

import com.uniflow.common.PageResult;
import com.uniflow.common.Result;
import com.uniflow.entity.FormData;
import com.uniflow.service.FormDataService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 表单数据管理控制器
 */
@Api(tags = "表单数据管理")
@RestController
@RequestMapping("/api/v1/form-data")
public class FormDataController {
    
    @Autowired
    private FormDataService formDataService;
    
    /**
     * 分页查询表单数据列表
     */
    @ApiOperation("分页查询表单数据列表")
    @GetMapping
    public Result<PageResult<FormData>> getFormDataList(
            @ApiParam("页码") @RequestParam(defaultValue = "1") int pageNum,
            @ApiParam("页大小") @RequestParam(defaultValue = "10") int pageSize,
            @ApiParam("表单ID") @RequestParam(required = false) String formId,
            @ApiParam("业务键") @RequestParam(required = false) String businessKey,
            @ApiParam("流程实例ID") @RequestParam(required = false) String processInstanceId,
            @ApiParam("任务ID") @RequestParam(required = false) String taskId,
            @ApiParam("状态") @RequestParam(required = false) String status,
            @ApiParam("提交人") @RequestParam(required = false) String submittedBy,
            @ApiParam("审核人") @RequestParam(required = false) String reviewedBy,
            @ApiParam("开始时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startDate,
            @ApiParam("结束时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endDate) {
        
        PageResult<FormData> result = formDataService.getFormDataList(pageNum, pageSize, formId, 
                businessKey, processInstanceId, taskId, status, submittedBy, reviewedBy, 
                startDate, endDate);
        return Result.success(result);
    }
    
    /**
     * 根据ID查询表单数据详情
     */
    @ApiOperation("根据ID查询表单数据详情")
    @GetMapping("/{id}")
    public Result<FormData> getFormDataById(@ApiParam("表单数据ID") @PathVariable String id) {
        FormData formData = formDataService.getFormDataById(id);
        if (formData == null) {
            return Result.error("表单数据不存在");
        }
        return Result.success(formData);
    }
    
    /**
     * 根据表单ID和业务键查询表单数据
     */
    @ApiOperation("根据表单ID和业务键查询表单数据")
    @GetMapping("/form/{formId}/business/{businessKey}")
    public Result<FormData> getFormDataByFormIdAndBusinessKey(
            @ApiParam("表单ID") @PathVariable String formId,
            @ApiParam("业务键") @PathVariable String businessKey) {
        FormData formData = formDataService.getFormDataByFormIdAndBusinessKey(formId, businessKey);
        if (formData == null) {
            return Result.error("表单数据不存在");
        }
        return Result.success(formData);
    }
    
    /**
     * 根据流程实例ID查询表单数据列表
     */
    @ApiOperation("根据流程实例ID查询表单数据列表")
    @GetMapping("/process/{processInstanceId}")
    public Result<List<FormData>> getFormDataByProcessInstanceId(
            @ApiParam("流程实例ID") @PathVariable String processInstanceId) {
        List<FormData> formDataList = formDataService.getFormDataByProcessInstanceId(processInstanceId);
        return Result.success(formDataList);
    }
    
    /**
     * 根据任务ID查询表单数据
     */
    @ApiOperation("根据任务ID查询表单数据")
    @GetMapping("/task/{taskId}")
    public Result<FormData> getFormDataByTaskId(@ApiParam("任务ID") @PathVariable String taskId) {
        FormData formData = formDataService.getFormDataByTaskId(taskId);
        if (formData == null) {
            return Result.error("表单数据不存在");
        }
        return Result.success(formData);
    }
    
    /**
     * 根据提交人查询表单数据列表
     */
    @ApiOperation("根据提交人查询表单数据列表")
    @GetMapping("/submitter/{submittedBy}")
    public Result<List<FormData>> getFormDataBySubmittedBy(
            @ApiParam("提交人") @PathVariable String submittedBy,
            @ApiParam("状态") @RequestParam(required = false) String status) {
        List<FormData> formDataList = formDataService.getFormDataBySubmittedBy(submittedBy, status);
        return Result.success(formDataList);
    }
    
    /**
     * 提交表单数据
     */
    @ApiOperation("提交表单数据")
    @PostMapping("/submit")
    public Result<FormData> submitFormData(@Valid @RequestBody SubmitFormDataRequest request) {
        FormData formData = new FormData();
        formData.setFormId(request.getFormId());
        formData.setBusinessKey(request.getBusinessKey());
        formData.setProcessInstanceId(request.getProcessInstanceId());
        formData.setTaskId(request.getTaskId());
        formData.setData(request.getData());
        formData.setSubmittedBy(request.getSubmittedBy());
        formData.setSubmittedByName(request.getSubmittedByName());
        formData.setRemark(request.getRemark());
        
        FormData submittedFormData = formDataService.submitFormData(formData);
        return Result.success(submittedFormData);
    }
    
    /**
     * 保存草稿
     */
    @ApiOperation("保存草稿")
    @PostMapping("/draft")
    public Result<FormData> saveDraft(@Valid @RequestBody SaveDraftRequest request) {
        FormData formData = new FormData();
        formData.setId(request.getId());
        formData.setFormId(request.getFormId());
        formData.setBusinessKey(request.getBusinessKey());
        formData.setProcessInstanceId(request.getProcessInstanceId());
        formData.setTaskId(request.getTaskId());
        formData.setData(request.getData());
        formData.setSubmittedBy(request.getSubmittedBy());
        formData.setSubmittedByName(request.getSubmittedByName());
        formData.setRemark(request.getRemark());
        
        FormData savedFormData = formDataService.saveDraft(formData);
        return Result.success(savedFormData);
    }
    
    /**
     * 更新表单数据
     */
    @ApiOperation("更新表单数据")
    @PutMapping("/{id}")
    public Result<FormData> updateFormData(@ApiParam("表单数据ID") @PathVariable String id,
                                          @Valid @RequestBody UpdateFormDataRequest request) {
        FormData formData = formDataService.getFormDataById(id);
        if (formData == null) {
            return Result.error("表单数据不存在");
        }
        
        formData.setFormId(request.getFormId());
        formData.setBusinessKey(request.getBusinessKey());
        formData.setData(request.getData());
        formData.setRemark(request.getRemark());
        
        FormData updatedFormData = formDataService.updateFormData(formData);
        return Result.success(updatedFormData);
    }
    
    /**
     * 删除表单数据
     */
    @ApiOperation("删除表单数据")
    @DeleteMapping("/{id}")
    public Result<Void> deleteFormData(@ApiParam("表单数据ID") @PathVariable String id) {
        formDataService.deleteFormData(id);
        return Result.success();
    }
    
    /**
     * 批量删除表单数据
     */
    @ApiOperation("批量删除表单数据")
    @DeleteMapping("/batch")
    public Result<Void> batchDeleteFormData(@RequestBody BatchDeleteRequest request) {
        formDataService.batchDeleteFormData(request.getIds());
        return Result.success();
    }
    
    /**
     * 审核表单数据
     */
    @ApiOperation("审核表单数据")
    @PostMapping("/{id}/review")
    public Result<Void> reviewFormData(@ApiParam("表单数据ID") @PathVariable String id,
                                      @RequestBody ReviewFormDataRequest request) {
        formDataService.reviewFormData(id, request.getStatus(), request.getReviewComment(),
                request.getReviewedBy(), request.getReviewedByName());
        return Result.success();
    }
    
    /**
     * 批量审核表单数据
     */
    @ApiOperation("批量审核表单数据")
    @PostMapping("/batch-review")
    public Result<Void> batchReviewFormData(@RequestBody BatchReviewFormDataRequest request) {
        formDataService.batchReviewFormData(request.getIds(), request.getStatus(), 
                request.getReviewComment(), request.getReviewedBy(), request.getReviewedByName());
        return Result.success();
    }
    
    /**
     * 更新表单数据状态
     */
    @ApiOperation("更新表单数据状态")
    @PostMapping("/{id}/status")
    public Result<Void> updateFormDataStatus(@ApiParam("表单数据ID") @PathVariable String id,
                                             @RequestBody UpdateStatusRequest request) {
        formDataService.updateFormDataStatus(id, request.getStatus());
        return Result.success();
    }
    
    /**
     * 检查业务键是否存在
     */
    @ApiOperation("检查业务键是否存在")
    @GetMapping("/check-business-key")
    public Result<Boolean> checkBusinessKeyExists(
            @ApiParam("业务键") @RequestParam String businessKey,
            @ApiParam("排除的表单数据ID") @RequestParam(required = false) String excludeId) {
        boolean exists = formDataService.isBusinessKeyExists(businessKey, excludeId);
        return Result.success(exists);
    }
    
    /**
     * 获取表单数据统计信息
     */
    @ApiOperation("获取表单数据统计信息")
    @GetMapping("/statistics")
    public Result<Map<String, Object>> getFormDataStatistics(
            @ApiParam("表单ID") @RequestParam(required = false) String formId) {
        Map<String, Object> statistics = formDataService.getFormDataStatistics(formId);
        return Result.success(statistics);
    }
    
    /**
     * 根据表单统计数据量
     */
    @ApiOperation("根据表单统计数据量")
    @GetMapping("/count-by-form")
    public Result<List<Map<String, Object>>> getFormDataCountByForm(
            @ApiParam("限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        List<Map<String, Object>> statistics = formDataService.getFormDataCountByForm(limit);
        return Result.success(statistics);
    }
    
    /**
     * 根据状态统计数据量
     */
    @ApiOperation("根据状态统计数据量")
    @GetMapping("/count-by-status")
    public Result<List<Map<String, Object>>> getFormDataCountByStatus(
            @ApiParam("表单ID") @RequestParam(required = false) String formId) {
        List<Map<String, Object>> statistics = formDataService.getFormDataCountByStatus(formId);
        return Result.success(statistics);
    }
    
    /**
     * 根据提交人统计数据量
     */
    @ApiOperation("根据提交人统计数据量")
    @GetMapping("/count-by-submitter")
    public Result<List<Map<String, Object>>> getFormDataCountBySubmitter(
            @ApiParam("表单ID") @RequestParam(required = false) String formId,
            @ApiParam("限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        List<Map<String, Object>> statistics = formDataService.getFormDataCountBySubmitter(formId, limit);
        return Result.success(statistics);
    }
    
    /**
     * 根据时间统计数据量
     */
    @ApiOperation("根据时间统计数据量")
    @GetMapping("/count-by-date")
    public Result<List<Map<String, Object>>> getFormDataCountByDate(
            @ApiParam("表单ID") @RequestParam(required = false) String formId,
            @ApiParam("开始时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startDate,
            @ApiParam("结束时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endDate) {
        List<Map<String, Object>> statistics = formDataService.getFormDataCountByDate(formId, startDate, endDate);
        return Result.success(statistics);
    }
    
    /**
     * 根据时间统计数据量（按月）
     */
    @ApiOperation("根据时间统计数据量（按月）")
    @GetMapping("/count-by-month")
    public Result<List<Map<String, Object>>> getFormDataCountByMonth(
            @ApiParam("表单ID") @RequestParam(required = false) String formId,
            @ApiParam("开始时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startDate,
            @ApiParam("结束时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endDate) {
        List<Map<String, Object>> statistics = formDataService.getFormDataCountByMonth(formId, startDate, endDate);
        return Result.success(statistics);
    }
    
    /**
     * 获取待处理的表单数据数量
     */
    @ApiOperation("获取待处理的表单数据数量")
    @GetMapping("/pending-count")
    public Result<Integer> getPendingFormDataCount(
            @ApiParam("处理人") @RequestParam String assignee) {
        int count = formDataService.getPendingFormDataCount(assignee);
        return Result.success(count);
    }
    
    /**
     * 获取我的表单数据统计
     */
    @ApiOperation("获取我的表单数据统计")
    @GetMapping("/my-statistics")
    public Result<Map<String, Object>> getMyFormDataStatistics(
            @ApiParam("用户ID") @RequestParam String userId) {
        Map<String, Object> statistics = formDataService.getMyFormDataStatistics(userId);
        return Result.success(statistics);
    }
    
    /**
     * 导出表单数据
     */
    @ApiOperation("导出表单数据")
    @GetMapping("/export")
    public Result<List<Map<String, Object>>> exportFormData(
            @ApiParam("表单ID") @RequestParam String formId,
            @ApiParam("状态") @RequestParam(required = false) String status,
            @ApiParam("开始时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startDate,
            @ApiParam("结束时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endDate) {
        List<Map<String, Object>> data = formDataService.exportFormData(formId, status, startDate, endDate);
        return Result.success(data);
    }
    
    /**
     * 生成表单数据报表
     */
    @ApiOperation("生成表单数据报表")
    @GetMapping("/report")
    public Result<Map<String, Object>> generateFormDataReport(
            @ApiParam("表单ID") @RequestParam String formId,
            @ApiParam("报表类型") @RequestParam String reportType,
            @ApiParam("开始时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startDate,
            @ApiParam("结束时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endDate) {
        Map<String, Object> report = formDataService.generateFormDataReport(formId, reportType, startDate, endDate);
        return Result.success(report);
    }
    
    // 请求数据结构
    
    public static class SubmitFormDataRequest {
        private String formId;
        private String businessKey;
        private String processInstanceId;
        private String taskId;
        private Map<String, Object> data;
        private String submittedBy;
        private String submittedByName;
        private String remark;
        
        // getters and setters
        public String getFormId() { return formId; }
        public void setFormId(String formId) { this.formId = formId; }
        public String getBusinessKey() { return businessKey; }
        public void setBusinessKey(String businessKey) { this.businessKey = businessKey; }
        public String getProcessInstanceId() { return processInstanceId; }
        public void setProcessInstanceId(String processInstanceId) { this.processInstanceId = processInstanceId; }
        public String getTaskId() { return taskId; }
        public void setTaskId(String taskId) { this.taskId = taskId; }
        public Map<String, Object> getData() { return data; }
        public void setData(Map<String, Object> data) { this.data = data; }
        public String getSubmittedBy() { return submittedBy; }
        public void setSubmittedBy(String submittedBy) { this.submittedBy = submittedBy; }
        public String getSubmittedByName() { return submittedByName; }
        public void setSubmittedByName(String submittedByName) { this.submittedByName = submittedByName; }
        public String getRemark() { return remark; }
        public void setRemark(String remark) { this.remark = remark; }
    }
    
    public static class SaveDraftRequest {
        private String id;
        private String formId;
        private String businessKey;
        private String processInstanceId;
        private String taskId;
        private Map<String, Object> data;
        private String submittedBy;
        private String submittedByName;
        private String remark;
        
        // getters and setters
        public String getId() { return id; }
        public void setId(String id) { this.id = id; }
        public String getFormId() { return formId; }
        public void setFormId(String formId) { this.formId = formId; }
        public String getBusinessKey() { return businessKey; }
        public void setBusinessKey(String businessKey) { this.businessKey = businessKey; }
        public String getProcessInstanceId() { return processInstanceId; }
        public void setProcessInstanceId(String processInstanceId) { this.processInstanceId = processInstanceId; }
        public String getTaskId() { return taskId; }
        public void setTaskId(String taskId) { this.taskId = taskId; }
        public Map<String, Object> getData() { return data; }
        public void setData(Map<String, Object> data) { this.data = data; }
        public String getSubmittedBy() { return submittedBy; }
        public void setSubmittedBy(String submittedBy) { this.submittedBy = submittedBy; }
        public String getSubmittedByName() { return submittedByName; }
        public void setSubmittedByName(String submittedByName) { this.submittedByName = submittedByName; }
        public String getRemark() { return remark; }
        public void setRemark(String remark) { this.remark = remark; }
    }
    
    public static class UpdateFormDataRequest {
        private String formId;
        private String businessKey;
        private Map<String, Object> data;
        private String remark;
        
        // getters and setters
        public String getFormId() { return formId; }
        public void setFormId(String formId) { this.formId = formId; }
        public String getBusinessKey() { return businessKey; }
        public void setBusinessKey(String businessKey) { this.businessKey = businessKey; }
        public Map<String, Object> getData() { return data; }
        public void setData(Map<String, Object> data) { this.data = data; }
        public String getRemark() { return remark; }
        public void setRemark(String remark) { this.remark = remark; }
    }
    
    public static class BatchDeleteRequest {
        private List<String> ids;
        
        public List<String> getIds() { return ids; }
        public void setIds(List<String> ids) { this.ids = ids; }
    }
    
    public static class ReviewFormDataRequest {
        private String status;
        private String reviewComment;
        private String reviewedBy;
        private String reviewedByName;
        
        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
        public String getReviewComment() { return reviewComment; }
        public void setReviewComment(String reviewComment) { this.reviewComment = reviewComment; }
        public String getReviewedBy() { return reviewedBy; }
        public void setReviewedBy(String reviewedBy) { this.reviewedBy = reviewedBy; }
        public String getReviewedByName() { return reviewedByName; }
        public void setReviewedByName(String reviewedByName) { this.reviewedByName = reviewedByName; }
    }
    
    public static class BatchReviewFormDataRequest {
        private List<String> ids;
        private String status;
        private String reviewComment;
        private String reviewedBy;
        private String reviewedByName;
        
        public List<String> getIds() { return ids; }
        public void setIds(List<String> ids) { this.ids = ids; }
        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
        public String getReviewComment() { return reviewComment; }
        public void setReviewComment(String reviewComment) { this.reviewComment = reviewComment; }
        public String getReviewedBy() { return reviewedBy; }
        public void setReviewedBy(String reviewedBy) { this.reviewedBy = reviewedBy; }
        public String getReviewedByName() { return reviewedByName; }
        public void setReviewedByName(String reviewedByName) { this.reviewedByName = reviewedByName; }
    }
    
    public static class UpdateStatusRequest {
        private String status;
        
        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
    }
}